export class DoubleMap<K, V>
{
    private readonly kv = new Map<K, V>();
    private readonly vk = new Map<V, K>();

    public ForEach(action) {
        if (action == null) {
            return;
        }
    }


    public Add(key: K, value: V) {
        if (key == null || value == null || this.kv.has(key) || this.vk.has(value)) {
            return;
        }
        this.kv.set(key, value);
        this.vk.set(value, key);
    }

    public GetValueByKey(key: K): V {
        if (key != null && this.kv.has(key)) {
            return this.kv.get(key);
        }
        return null;
    }

    public GetKeyByValue(value: V): K {
        if (value != null && this.vk.has(value)) {
            return this.vk.get(value);
        }
        return null;
    }

    public RemoveByKey(key: K) {
        if (key == null) {
            return;
        }
        let value = this.kv.get(key);
        if (!value) {
            return;
        }

        this.kv.delete(key);
        this.vk.delete(value);
    }

    public RemoveByValue(value: V) {
        if (value == null) {
            return;
        }

        let key = this.vk.get(value);
        if (!key) {
            return;
        }

        this.kv.delete(key);
        this.vk.delete(value);
    }

    public Clear() {
        this.kv.clear();
        this.vk.clear();
    }

    public ContainsKey(key: K) {
        if (key == null) {
            return false;
        }
        return this.kv.has(key);
    }

    public ContainsValue(value: V) {
        if (value == null) {
            return false;
        }
        return this.vk.has(value);
    }

    public Contains(key: K, value: V) {
        if (key == null || value == null) {
            return false;
        }
        return this.kv.has(key) && this.vk.has(value);
    }
}